type EventMap = {
  /** 传送门 */
  portal: (params: { el: any; type: 'render' | 'remove' }) => void
  portalRoute: (params: { el: any; type: 'render' | 'remove' }) => void
  /** 城市选择 */
  'area-picker': (params: { type: 'reject' | 'resolve'; data?: any; trackId: string }) => any
  /** 地址选择 */
  'choose-address': (params: { type: 'reject' | 'resolve'; data?: any; trackId: string }) => any
  /** 城市选择-平铺 */
  'choose-city': (params: { type: 'reject' | 'resolve'; data?: any; trackId: string }) => any
  /** 选择门店 */
  'choose-collaborator': (params: { type: 'reject' | 'resolve'; data?: any; trackId: string }) => any
  /** 选择约会对象 */
  'choose-datingService': (params: { type: 'reject' | 'resolve'; data?: any; trackId: string }) => any
  /** 更新待办提醒当前页码数据 */
  refreshRemindCurrentPage: () => any
  /** 登录 */
  onLogged: (token: string) => any
  /** 退出登录 */
  onLogout: () => any
}

/** 简易发布订阅模式 */
function createStore() {
  /** 事件订阅中心 */
  const listener = []
  // 控制publish时subscribe未注册的情况,将publish参数缓存
  const cachePublish: any = []

  /** 事件监听 */
  function subscribe<E extends keyof EventMap>(eventName: E, fn: EventMap[E]) {
    listener.push({ eventName, fn })
    if (cachePublish.length) {
      const cache = cachePublish.slice(0)
      cache.forEach((item) => {
        const i = cachePublish.findIndex((each) => each.eventName === eventName)
        if (i > -1) {
          publish(item.eventName, item.data)
          const i = cachePublish.findIndex((each) => each.eventName === eventName)
          cachePublish.splice(i, 1)
        }
      })
    }
    return () => {
      listener.splice(
        listener.findIndex((item) => item.eventName === eventName && item.fn === fn),
        1
      )
    }
  }

  /** 事件触发 */
  function publish<E extends keyof EventMap>(eventName: E, data?: Parameters<EventMap[E]>[0]) {
    // 当subscribe未注册时进入此逻辑
    const current = listener.find((each) => each.eventName === eventName)
    if (!current) {
      cachePublish.push({ eventName, data })
    } else {
      listener.forEach((item) => {
        if (item.eventName === eventName) {
          item?.fn(data)
        }
      })
    }
  }

  return { subscribe, publish }
}

export const eventStore = createStore()
